#ifndef HALCON_PROCESSOR_INTERFACE_HPP
#define HALCON_PROCESSOR_INTERFACE_HPP

#include <Pluma/Pluma.hpp>
#include "HalconCpp.h"
#include <exception>

using namespace HalconCpp;
using namespace std;


struct CircleMark
{
    bool ifWrong;
    std::string note;
    uint centerX;
    uint centerY;
    uint radius;
};

struct HalconResult{
    std::vector<CircleMark> circleMarkVector;
    bool ifFail;
    std::string failureReason;
};

/////////////////////////////////////////////////////////
/// Warrior Interface
/// That's the kind of objects that plugins will provide.
/////////////////////////////////////////////////////////
class HalconProcessorInterface{
public:
    virtual uint getId() = 0;
    // (...)
    virtual std::string getDescription()=0;

    virtual void processImage(const HalconCpp::HObject& ho_image, HalconResult& result) =0;

    void process(const HalconCpp::HObject& ho_image, HalconResult& result){
        try {
            result.ifFail = false;
            processImage(ho_image,result);
        }
        catch(HException& e){
            result.ifFail = true;
            result.failureReason = e.ErrorMessage();
        }
        catch(std::exception& e) {
            result.ifFail = true;
            result.failureReason = e.what();
        }
    }
};


/////////////////////////////////////////////////////////
/// WarriorProvider Interface
/// Plugins will provide host with new Warriors throgh WarriorProvider
/// implementations. Host automatically check version compatibility.
/////////////////////////////////////////////////////////
// PLUMA_GEN_PROVIDER(Type, current_version, lowest_compatible_version)
PLUMA_PROVIDER_HEADER(HalconProcessorInterface);


// - Advanced example of provider header generation
//PLUMA_PROVIDER_HEADER_BEGIN(Warrior)
//    public:
//        virtual Warrior* create(int energy) = 0;
//        virtual void populate(std::vector<Warrior*>& army, int numSoldiers) = 0;
//PLUMA_PROVIDER_HEADER_END


#endif // WARRIOR_HPP
